home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac Magazin/MacEasy 32
/
Mac Magazin and MacEasy Magazine CD - Issue 32.iso
/
Multimedia
/
PlayerPRO 4.5.5 Dev.Kit
/
Plug-Ins
/
Music Import⁄Export Plugs
/
Mod.c
< prev
next >
Wrap
Text File
|
1997-02-25
|
24KB
|
888 lines
/******************** ***********************/
//
// Player PRO 4.5x -- MOD to MADx & MADx to MOD
//
// Version 1.0 - 12.3.95 ANR
//
// To use with CodeWarrior 68K or PPC
//
// Antoine ROSSET
// 16 Tranchees
// 1206 GENEVA
// SWITZERLAND
//
// FAX: (+41 22) 346 11 97
// Compuserve: 100277,164
// Internet: rosset@dial.eunet.ch
//
/******************** ***********************/
#include "RDriver.h"
#include "MOD.h"
#include "FileUtils.h"
#ifdef _MAC_H
#if defined(powerc) || defined(__powerc)
enum {
PlayerPROPlug = kCStackBased
| RESULT_SIZE(SIZE_CODE(sizeof(OSErr)))
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof( OSType)))
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof( Ptr)))
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof( MADPartition*)))
| STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof( PPInfoRec*)))
| STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof( MADDriverSettings*)))
};
ProcInfoType __procinfo = PlayerPROPlug;
#else
#include <A4Stuff.h>
#endif
#endif
debugger(Ptr);
short FoundNote( short Period)
{
short note;
short MODTuning[ 65] =
{
// -> Tuning 0
1712,1616,1524,1440,1356,1280,1208,1140,1076,1016,960,906,
856,808,762,720,678,640,604,570,538,508,480,453,
428,404,381,360,339,320,302,285,269,254,240,226,
214,202,190,180,170,160,151,143,135,127,120,113,
107,101,95,90,85,80,75,71,67,63,60,56
};
note = 0xFF;
if(Period != 0)
{
for(note = 0;note < 60;note++)
{
if(Period >= MODTuning[ note]) break;
}
if(note >= NUMBER_NOTES) note = 0xFF;
}
if( note != 0xFF) note += 24;
return note;
}
Cmd* GetMADCommand( register short PosX, register short TrackIdX, register PatData* tempMusicPat)
{
if( PosX < 0) PosX = 0;
else if( PosX >= tempMusicPat->header.size) PosX = tempMusicPat->header.size -1;
return( & (tempMusicPat->Cmds[ (tempMusicPat->header.size * TrackIdX) + PosX]));
}
Ptr MADNewPtr( long size, MADDriverSettings* init)
{
if( init->sysMemory) return NewPtrSys( size);
else return NewPtr( size);
}
Ptr MADNewPtrClear( long size, MADDriverSettings* init)
{
if( init->sysMemory) return NewPtrSysClear( size);
else return NewPtrClear( size);
}
void AnalyseSignatureMOD( long EOFo, long temp, short *maxInstru, long *PatternSize, short *tracksNo, MODDef* aMOD)
{
long test, i;
Boolean result;
*maxInstru = 31;
MOT32( &temp);
switch( temp)
{
case 'FLT4': *PatternSize = sizeof( struct MODCom) * 64L * 4L; *tracksNo = 4; break;
case 'FLT8': *PatternSize = sizeof( struct MODCom) * 64L * 4L; *tracksNo = 4; break;
case 'M.K.': *PatternSize = sizeof( struct MODCom) * 64L * 4L; *tracksNo = 4; break;
case '5CHN': *PatternSize = sizeof( struct MODCom) * 64L * 5L; *tracksNo = 5; break;
case '6CHN': *PatternSize = sizeof( struct MODCom) * 64L * 6L; *tracksNo = 6; break;
case '7CHN': *PatternSize = sizeof( struct MODCom) * 64L * 7L; *tracksNo = 7; break;
case '8CHN': *PatternSize = sizeof( struct MODCom) * 64L * 8L; *tracksNo = 8; break;
case '9CHN': *PatternSize = sizeof( struct MODCom) * 64L * 9L; *tracksNo = 9; break;
case '10CH': *PatternSize = sizeof( struct MODCom) * 64L * 10L; *tracksNo = 10; break;
case '11CH': *PatternSize = sizeof( struct MODCom) * 64L * 11L; *tracksNo = 11; break;
case '12CH': *PatternSize = sizeof( struct MODCom) * 64L * 12L; *tracksNo = 12; break;
case '13CH': *PatternSize = sizeof( struct MODCom) * 64L * 13L; *tracksNo = 13; break;
case '14CH': *PatternSize = sizeof( struct MODCom) * 64L * 14L; *tracksNo = 14; break;
case '15CH': *PatternSize = sizeof( struct MODCom) * 64L * 15L; *tracksNo = 15; break;
case '16CH': *PatternSize = sizeof( struct MODCom) * 64L * 16L; *tracksNo = 16; break;
case '17CH': *PatternSize = sizeof( struct MODCom) * 64L * 17L; *tracksNo = 17; break;
case '18CH': *PatternSize = sizeof( struct MODCom) * 64L * 18L; *tracksNo = 18; break;
case '19CH': *PatternSize = sizeof( struct MODCom) * 64L * 19L; *tracksNo = 19; break;
case '20CH': *PatternSize = sizeof( struct MODCom) * 64L * 20L; *tracksNo = 20; break;
case '21CH': *PatternSize = sizeof( struct MODCom) * 64L * 21L; *tracksNo = 21; break;
case '22CH': *PatternSize = sizeof( struct MODCom) * 64L * 22L; *tracksNo = 22; break;
case '23CH': *PatternSize = sizeof( struct MODCom) * 64L * 23L; *tracksNo = 23; break;
case '24CH': *PatternSize = sizeof( struct MODCom) * 64L * 24L; *tracksNo = 24; break;
case '25CH': *PatternSize = sizeof( struct MODCom) * 64L * 25L; *tracksNo = 25; break;
case '26CH': *PatternSize = sizeof( struct MODCom) * 64L * 26L; *tracksNo = 26; break;
case '27CH': *PatternSize = sizeof( struct MODCom) * 64L * 27L; *tracksNo = 27; break;
case '28CH': *PatternSize = sizeof( struct MODCom) * 64L * 28L; *tracksNo = 28; break;
case '29CH': *PatternSize = sizeof( struct MODCom) * 64L * 29L; *tracksNo = 29; break;
case '30CH': *PatternSize = sizeof( struct MODCom) * 64L * 30L; *tracksNo = 30; break;
case '31CH': *PatternSize = sizeof( struct MODCom) * 64L * 31L; *tracksNo = 31; break;
case '32CH': *PatternSize = sizeof( struct MODCom) * 64L * 32L; *tracksNo = 32; break;
default:
*PatternSize = sizeof( struct MODCom) * 64L * 4L; *tracksNo = 4;
result = true;
test = 0;
for( i = 0; i < 15; i++)
{
test += aMOD->fid[i].numWords;
if( aMOD->fid[i].fineTune > 0x0F) result = false;
if( aMOD->fid[i].loopWords > aMOD->fid[i].numWords) result = false;
}
if( EOFo != -1)
{
long PatMax = 0;
for(i=0; i<128; i++)
{
if( aMOD->oPointers[i] < 0) aMOD->oPointers[i] = 0;
if( aMOD->oPointers[i] > 128) aMOD->oPointers[i] = 0;
if( aMOD->oPointers[i] >= PatMax) PatMax = aMOD->oPointers[i];
}
PatMax++;
if( PatMax * *PatternSize + test > EOFo) result = false;
}
if( test == 0) result = false;
if( result) *maxInstru = 15;
else *maxInstru = 0;
break;
}
}
struct MODCom* GetMODCommand( short position, short whichTracks, short whichPattern, short maxTracks, Ptr PatPtr)
{
struct MODCom* myMODCom;
myMODCom = (struct MODCom*) (PatPtr +
whichPattern * 64L * sizeof( struct MODCom) * maxTracks +
position * sizeof( struct MODCom) * maxTracks +
whichTracks * sizeof( struct MODCom));
return myMODCom;
}
OSErr PPConvertMod2Mad( Ptr aMOD,long MODSize, MADPartition *theMAD, MADDriverSettings* init)
{
short i, PatMax, x, tracksNo, z, maxInstru;
long sndSize, OffSetToSample, MPatSize, temp, inOutCount;
Ptr theInstrument[ 64], MaxPtr;
long finetune[16] =
{
8363, 8413, 8463, 8529, 8581, 8651, 8723, 8757,
7895, 7941, 7985, 8046, 8107, 8169, 8232, 8280
};
/**** Variables for MAD File *****/
Cmd *aCmd;
/**** Variables for MOD File *****/
MODDef *theMOD;
struct MODPat *PatInt;
MODDef *MODInt;
struct MODCom *n;
/********************************/
theMOD = ((MODDef*) aMOD);
MaxPtr = (Ptr)((long) theMOD + MODSize);
temp = *((long*)(aMOD + 0x438)); // Signature...
AnalyseSignatureMOD( -1, temp, &maxInstru, &MPatSize, &tracksNo, theMOD);
if( maxInstru == 0)
{
return MADFileNotSupportedByThisPlug; // This file is NOT a Mod file !!!!!! This should NEVER happen !
}
else if( maxInstru == 15) // Old Mods format with 15 instruments
{
MODInt = (MODDef*) ( (Ptr) theMOD - (Ptr) 0x1E0);
PatInt = (struct MODPat*) ((Ptr) MODInt->patterns - (Ptr) 0x4);
PatMax = 0;
for(i=0; i<128; i++)
{
if( MODInt->oPointers[i] < 0) MODInt->oPointers[i] = 0;
if( MODInt->oPointers[i] > 128) MODInt->oPointers[i] = 0;
if( MODInt->oPointers[i] >= PatMax) PatMax = MODInt->oPointers[i];
}
PatMax++;
// if( MODInt->numPointers > 64) MODInt->numPointers = 64;
// for(i=64; i<128; i++) MODInt->oPointers[i] = 0;
OffSetToSample = (long) 0x258 + PatMax * MPatSize;
}
else // Mods format with 32 instruments
{
MODInt = theMOD;
PatInt = MODInt->patterns;
PatMax = 0;
for(i=0; i<128; i++)
{
if( MODInt->oPointers[i] < 0) MODInt->oPointers[i] = 0;
if( MODInt->oPointers[i] > 128) MODInt->oPointers[i] = 0;
if( MODInt->oPointers[i] >= PatMax) PatMax = MODInt->oPointers[i];
}
PatMax++;
OffSetToSample = (long) 0x43c + PatMax * MPatSize;
}
for( i = 0; i < maxInstru ; i++)
{
theInstrument[ i] = (Ptr) ((long) theMOD + (long) OffSetToSample);
MOT16( &theMOD->fid[ i].numWords);
MOT16( &theMOD->fid[ i].loopWord);
MOT16( &theMOD->fid[ i].loopWords);
sndSize = ((long) theMOD->fid[i].numWords) * 2L;
if( theInstrument[i] + sndSize > MaxPtr)
{
theMOD->fid[i].numWords = MaxPtr - theInstrument[i];
theMOD->fid[i].numWords /= 2L;
if( theMOD->fid[i].numWords < 0) theMOD->fid[i].numWords = 0;
sndSize = ((long) theMOD->fid[i].numWords) * 2L;
}
OffSetToSample += sndSize;
if( theMOD->fid[i].loopWords > 2 && sndSize > 0)
{
if( (long) theMOD->fid[i].loopWord +
(long) theMOD->fid[i].loopWords >
(long) theMOD->fid[i].numWords)
{
theMOD->fid[ i].loopWords = (long) theMOD->fid[i].numWords -
(long) theMOD->fid[i].loopWord;
if( (long) theMOD->fid[i].loopWord +
(long) theMOD->fid[i].loopWords >
(long) theMOD->fid[i].numWords)
{
theMOD->fid[i].loopWord = 0;
theMOD->fid[i].loopWords = 0;
}
}
}
else
{
theMOD->fid[i].loopWord = 0;
theMOD->fid[i].loopWords = 0;
}
}
/***************************************************************/
/******** MOD is ready to be converted into MAD File ***********/
/***************************************************************/
inOutCount = sizeof( MADSpec);
theMAD->header = (MADSpec*) MADNewPtrClear( inOutCount, init);
if( theMAD->header == 0L) return MADNeedMemory;
strcpy( theMAD->header->infos, (Ptr) "Converted by PlayerPRO MOD Plug (©Antoine ROSSET <rosset@dial.eunet.ch>)");
theMAD->header->MAD = 'MADH';
for(i=0; i<22; i++) theMAD->header->name[i] = theMOD->NameSignature[i];
theMAD->header->tempo = 125;
theMAD->header->speed = 6;
theMAD->header->numPat = PatMax;
theMAD->header->numPointers = MODInt->numPointers;
for(i=0; i<128; i++) theMAD->header->oPointers[ i] = MODInt->oPointers[ i];
theMAD->header->numChn = tracksNo;
for(i = 0; i < maxInstru; i++)
{
for( x = 0; x < 22; x++) theMAD->header->fid[i].name[x] = theMOD->fid[i].Filename[x];
theMAD->header->fid[i].type = 0;
theMAD->header->fid[i].volFade = DEFAULT_VOLFADE;
if( theMOD->fid[ i].numWords > 0)
{
sData *curData;
theMAD->header->fid[i].numSamples = 1;
curData = theMAD->sample[ i][ 0] = (sData*) MADNewPtrClear( sizeof( sData), init);
curData->size = theMOD->fid[i].numWords * 2L;
curData->loopBeg = theMOD->fid[i].loopWord*2L;
curData->loopSize = theMOD->fid[i].loopWords*2L;
curData->vol = theMOD->fid[i].volume;
curData->c2spd = finetune[ theMOD->fid[i].fineTune];
curData->loopType = 0;
curData->amp = 8;
curData->panning = 0;
curData->relNote = 0;
// for( x = 0; x < 22; x++) curData->name[x] = theMOD->fid[ i].Filename[ x];
curData->data = MADNewPtr( curData->size, init);
if( curData->data == 0L) return MADNeedMemory;
BlockMove( theInstrument[i], curData->data, curData->size);
}
else theMAD->header->fid[ i].numSamples = 0;
}
for( i = maxInstru; i < MAXINSTRU ; i++)
{
theMAD->header->fid[ i].numSamples = 0;
}
for(i=0; i<theMAD->header->numPat; i++)
{
theMAD->partition[ i] = (PatData*) MADNewPtrClear( sizeof( PatData) + theMAD->header->numChn * 64L * sizeof( Cmd), init);
if( theMAD->partition[ i] == 0L) return MADNeedMemory;
theMAD->partition[ i]->header.size = 64L;
theMAD->partition[ i]->header.compMode = 'NONE';
for( x = 0; x < 20; x++) theMAD->partition[ i]->header.name[ x] = 0;
theMAD->partition[ i]->header.patBytes = 0L; theMAD->partition[ i]->header.unused2 = 0L;
MaxPtr = (Ptr) theMAD->partition[ i];
MaxPtr += sizeof( PatData) + theMAD->header->numChn * 64L * sizeof( Cmd);
for(x=0; x<64; x++)
{
for(z=0; z<theMAD->header->numChn; z++)
{
aCmd = GetMADCommand( x, z, theMAD->partition[ i]);
if( (Ptr) aCmd + sizeof( Cmd) > MaxPtr) return -1;
/////////////
n = GetMODCommand( x,
z,
i,
theMAD->header->numChn,
(Ptr) PatInt);
aCmd->ins = (n->a&0x10)|(n->c>>4);
aCmd->note = FoundNote( (((unsigned short)n->a&0xf)<<8)+n->b);
aCmd->cmd = n->c & 0x0F;
if( aCmd->cmd == 0x0C)
{
aCmd->vol = 0x10 + (n->d);
if( aCmd->arg > 0x50) aCmd->vol = 0x50;
aCmd->cmd = 0;
aCmd->arg = 0;
}
else
{
aCmd->arg = n->d;
aCmd->vol = 0xFF;
}
}
}
}
for( i = theMAD->header->numPat; i < MAXPATTERN ; i++) theMAD->partition[ i] = 0L;
return noErr;
}
void Convert16to8( Ptr srcPtr, Ptr destPtr, long size)
{
long i;
size /= 2;
for( i = 0; i < size; i ++)
{
destPtr[ i] = srcPtr[i*2];
}
}
long ConvertSampleC4SPD( Ptr src, long srcSize, short amp, long srcC4SPD, Ptr dst, long dstC4SPD)
{
short *src16 = (short*) src, *dst16 = (short*) dst;
Ptr src8 = src, dst8 = dst;
long x;
if( amp == 8)
{
for( x = 0; x < srcSize; x++)
{
dst8[ (x * dstC4SPD) / srcC4SPD] = src8[ x];
}
}
else
{
for( x = 0; x < srcSize/2; x++)
{
dst16[ (x * dstC4SPD) / srcC4SPD] = src16[ x];
}
}
return (srcSize * dstC4SPD) / srcC4SPD;
}
Ptr PPConvertMad2Mod( MADPartition *theMAD, MADDriverSettings *init, long *PtrSize)
{
short i, x, z, maxInstru;
long OffSetToSample, InstruSize, *alpha;
Ptr theInstrument[ 64], destPtr;
Boolean CheckGoodMod;
char redut[4];
short MODTuning[ 65] =
/* { 0,
1712,1616,1525,1440,1357,1281,1209,1141,1077,1017, 961, 907,
856,808,762,720,678,640,604,570,538,508,480,453,
428,404,381,360,339,320,302,285,269,254,240,226,
214,202,190,180,170,160,151,143,135,127,120,113,
107,101, 95, 90, 85, 80, 76, 71, 67, 64, 60, 57 };*/
{
// -> Tuning 0
1712,1616,1524,1440,1356,1280,1208,1140,1076,1016,960,906,
856,808,762,720,678,640,604,570,538,508,480,453,
428,404,381,360,339,320,302,285,269,254,240,226,
214,202,190,180,170,160,151,143,135,127,120,113,
107,101,95,90,85,80,75,71,67,63,60,56
};
/**** Variables for MAD file ****/
Cmd *aCmd;
/**** Variables for MOD file ****/
MODDef *theMOD;
struct MODCom *n;
/********************************/
maxInstru = 31;
InstruSize = 0;
for( i = 0; i < maxInstru ; i++)
{
if( theMAD->header->fid[ i].numSamples > 0)
{
theInstrument[ i] = theMAD->sample[ i][ 0]->data;
InstruSize += theMAD->sample[ i][ 0]->size;
}
}
/******** MAD is ready to be converted **********/
/******** Copy information in the MOD file ***/
*PtrSize = 0x43c + InstruSize + theMAD->header->numChn * 64L * theMAD->header->numPat * sizeof( struct MODCom);
theMOD = (MODDef*) MADNewPtr( *PtrSize, init);
if( theMOD == 0L) return 0L;
theMOD->longFmtSignature = 'M.K.';
if( theMAD->header->numChn > 4)
{
if( theMAD->header->numChn >= 10)
{
redut[0] = 0x30 + (theMAD->header->numChn / 10);
redut[1] = 0x30 + (theMAD->header->numChn - 10);
redut[2] = 'C';
redut[3] = 'H';
}
else
{
redut[0] = 0x30 + theMAD->header->numChn;
redut[1] = 'C';
redut[2] = 'H';
redut[3] = 'N';
}
alpha = (long*) redut;
theMOD->longFmtSignature = *alpha;
}
for(i=0; i<20; i++) theMOD->NameSignature[i] = theMAD->header->name[i];
CheckGoodMod = false;
theMOD->numPointers = theMAD->header->numPointers;
for(i=0; i<128; i++)
{
theMOD->oPointers[ i] = theMAD->header->oPointers[ i];
if( theMOD->oPointers[ i] == theMAD->header->numPat - 1) CheckGoodMod = true;
}
if( !CheckGoodMod) theMOD->oPointers[ theMOD->numPointers + 1] = theMAD->header->numPat - 1;
for(i=0; i<maxInstru; i++)
{
if( theMAD->header->fid[ i].numSamples > 0)
{
sData *curData = theMAD->sample[ i][ 0];
short temp;
for( x = 0; x < 22; x++) theMOD->fid[i].Filename[x] = theMAD->header->fid[i].name[x];
if( curData->size/2L > 0xFFFFUL) theMOD->fid[i].numWords = 0xFFFFUL;
else theMOD->fid[i].numWords = (short) (curData->size / 2L);
temp = (curData->c2spd - NOFINETUNE) / 50;
if( temp < 0) temp += 16;
theMOD->fid[i].fineTune = temp;
theMOD->fid[i].volume = curData->vol;
theMOD->fid[i].loopWord = curData->loopBeg / 2L;
theMOD->fid[i].loopWords = curData->loopSize / 2L;
if( curData->c2spd > 8757 || curData->c2spd < 7895)
{
theMOD->fid[i].fineTune = 0;
theMOD->fid[i].loopWord = ((curData->loopBeg / 2L) * 8363L) / curData->c2spd;
theMOD->fid[i].loopWords = ((curData->loopSize / 2L) * 8363L) / curData->c2spd;
theMOD->fid[i].numWords = (theMOD->fid[i].numWords * 8363L) / curData->c2spd;
}
}
else
{
for( x = 0; x < 22; x++) theMOD->fid[i].Filename[x] = 0;
theMOD->fid[i].numWords = 0;
theMOD->fid[i].fineTune = 0;
theMOD->fid[i].volume = 64;
theMOD->fid[i].loopWord = 0;
theMOD->fid[i].loopWords = 0;
}
}
InstruSize = 0L;
OffSetToSample = (long) 0x43c + theMAD->header->numPat * sizeof( struct MODCom) * 64L * theMAD->header->numChn;
for(i=0; i<maxInstru; i++)
{
sData *curData = theMAD->sample[ i][ 0];
destPtr = (Ptr) ((long) theMOD + (long) OffSetToSample + (long) InstruSize);
if( curData->c2spd > 8757 || curData->c2spd < 7895)
{
ConvertSampleC4SPD( theInstrument[ i], curData->size, curData->amp, curData->c2spd, destPtr, 8363);
}
else
{
BlockMove( theInstrument[i], destPtr, (long) (theMOD->fid[i].numWords) * 2L);
}
if( theMOD->fid[i].numWords > 0)
{
if( curData->amp == 16)
{
Convert16to8( destPtr,
destPtr,
(long) (theMOD->fid[i].numWords) * 2L);
theMOD->fid[i].loopWord /=2;
theMOD->fid[i].loopWords /=2;
theMOD->fid[i].numWords /= 2;
}
}
InstruSize += (long) (theMOD->fid[i].numWords) * 2L;
}
for(i=0; i<theMAD->header->numPat; i++)
{
for(x=0; x < 64; x++)
{
for(z=0; z < theMAD->header->numChn; z++)
{
short note;
aCmd = GetMADCommand( x,
z,
theMAD->partition[ i]);
n = GetMODCommand( x,
z,
i,
theMAD->header->numChn,
(Ptr) theMOD->patterns);
n->a = aCmd->ins & 0xF0;
n->c = (aCmd->ins & 0x0F)<<4;
if( aCmd->note != 0xFF && aCmd->note != 0xFE)
{
short curNote;
if( aCmd->ins != 0) curNote = aCmd->note + theMAD->sample[ aCmd->ins-1][ 0]->relNote;
else curNote = aCmd->note;
curNote -= 24;
if( curNote > 0 && curNote < 65) curNote = MODTuning[ curNote];
else curNote = 0;
n->b = curNote & 0xFF;
n->a = n->a + (curNote>>8);
}
else
{
n->b = 0;
n->a = n->a + 0x0;
}
if( aCmd->vol != 0xFF && aCmd->cmd == 0 && aCmd->arg == 0)
{
if( aCmd->vol >= 0x10 && aCmd->vol <= 0x50)
{
n->c = n->c + 0xC;
n->d = aCmd->vol - 0x10;
}
}
else
{
n->c = n->c + (aCmd->cmd & 0x0F);
n->d = aCmd->arg;
}
}
}
}
return( (Ptr) theMOD);
}
OSErr ExtractMODInfo( PPInfoRec *info, Ptr AlienFile)
{
MODDef *myMOD = ( MODDef*) AlienFile;
long PatternSize;
short i;
short maxInstru;
/*** Signature ***/
info->signature = myMOD->longFmtSignature;
/*** Internal name ***/
myMOD->NameSignature[ 19] = '\0';
strcpy( info->internalFileName, myMOD->NameSignature);
/*** Check MOD Type ***/
AnalyseSignatureMOD( -1, info->signature, &maxInstru, &PatternSize, &info->totalTracks, myMOD);
if( maxInstru == 0)
{
return MADFileNotSupportedByThisPlug;
}
else if( maxInstru == 15) // Old mod format
{
info->signature = '----';
myMOD = (MODDef*) ((Ptr) myMOD - (Ptr) 0x1E0);
}
/*** Total Patterns ***/
info->totalPatterns = 0;
for( i = 0; i < 128; i++)
{
if( myMOD->oPointers[ i] >= info->totalPatterns) info->totalPatterns = myMOD->oPointers[ i];
}
info->totalPatterns++;
/*** Partition Length ***/
info->partitionLength = myMOD->numPointers;
/*** Total Instruments ***/
for( i = 0, info->totalInstruments = 0; i < maxInstru ; i++)
{
if( myMOD->fid[ i].numWords > 5) info->totalInstruments++;
}
strcpy( info->formatDescription, "MOD Plug");
return noErr;
}
OSErr TestMODFile( Ptr AlienFile, long EOFo)
{
short maxInstru;
long PatternSize;
short tracksNo;
AnalyseSignatureMOD( EOFo, *((long*)(AlienFile + 0x438)), &maxInstru, &PatternSize, &tracksNo, (MODDef*) AlienFile);
if( maxInstru == 0) return MADFileNotSupportedByThisPlug;
else return noErr;
}
#ifndef _MAC_H
EXP OSErr FillPlug( PlugInfo *p) // Function USED IN DLL - For PC & BeOS
{
strcpy( p->type, ".MOD");
strcpy( p->MenuName, "MOD Files");
p->mode = 'EXIM';
return noErr;
}
#endif
/*****************/
/* MAIN FUNCTION */
/*****************/
EXP OSErr main( OSType order, Ptr AlienFileName, MADPartition *MadFile, PPInfoRec *info, MADDriverSettings *init)
{
OSErr myErr;
Ptr AlienFile;
long sndSize;
UNFILE iFileRefI;
#ifdef _MAC_H
#ifndef powerc
long oldA4 = SetCurrentA4(); //this call is necessary for strings in 68k code resources
#endif
#endif
myErr = noErr;
switch( order)
{
case 'IMPL':
iFileRefI = iFileOpen( AlienFileName);
if( iFileRefI)
{
sndSize = iGetEOF( iFileRefI);
// ** MEMORY Test Start
AlienFile = MADNewPtr( sndSize * 2L, init);
if( AlienFile == 0L) myErr = MADNeedMemory;
// ** MEMORY Test End
else
{
DisposPtr( AlienFile);
AlienFile = MADNewPtr( sndSize, init);
iRead( sndSize, AlienFile, iFileRefI);
myErr = TestMODFile( AlienFile, sndSize);
if( myErr == noErr)
{
myErr = PPConvertMod2Mad( AlienFile, sndSize, MadFile, init);
}
DisposPtr( AlienFile); AlienFile = 0L;
}
iClose( iFileRefI);
}
else myErr = MADReadingErr;
break;
case 'TEST':
iFileRefI = iFileOpen( AlienFileName);
if( iFileRefI)
{
sndSize = 5000L; // Read only 5000 first bytes for optimisation
AlienFile = MADNewPtr( sndSize, init);
if( AlienFile == 0L) myErr = MADNeedMemory;
else
{
iRead( sndSize, AlienFile, iFileRefI);
sndSize = iGetEOF( iFileRefI);
myErr = TestMODFile( AlienFile, sndSize);
DisposPtr( AlienFile); AlienFile = 0L;
}
iClose( iFileRefI);
}
else myErr = MADReadingErr;
break;
case 'EXPL':
AlienFile = PPConvertMad2Mod( MadFile, init, &sndSize);
if( AlienFile != 0L)
{
iFileCreate( AlienFileName, 'STrk');
iFileRefI = iFileOpen( AlienFileName);
if( iFileRefI)
{
iWrite( sndSize, AlienFile, iFileRefI);
iClose( iFileRefI);
}
DisposPtr( AlienFile); AlienFile = 0L;
}
else myErr = MADReadingErr;
break;
case 'INFO':
iFileRefI = iFileOpen( AlienFileName);
if( iFileRefI)
{
info->fileSize = iGetEOF( iFileRefI);
sndSize = 5000L; // Read only 5000 first bytes for optimisation
AlienFile = MADNewPtr( sndSize, init);
if( AlienFile == 0L) myErr = MADNeedMemory;
else
{
iRead( sndSize, AlienFile, iFileRefI);
myErr = ExtractMODInfo( info, AlienFile);
DisposPtr( AlienFile); AlienFile = 0L;
}
iClose( iFileRefI);
}
else myErr = MADReadingErr;
break;
default:
myErr = MADOrderNotImplemented;
break;
}
#ifdef _MAC_H
#ifndef powerc
SetA4( oldA4);
#endif
#endif
return myErr;
}